package org.elastic.compreplatform.admin.core.shiro.token;

import java.util.Date;
import java.util.Set;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AccountException;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.elastic.compreplatform.admin.core.shiro.token.manager.TokenManager;
import org.elastic.compreplatform.admin.manager.sysuser.model.SysUser;
import org.elastic.compreplatform.admin.manager.sysuser.service.IPermissionService;
import org.elastic.compreplatform.admin.manager.sysuser.service.IRoleService;
import org.elastic.compreplatform.admin.manager.sysuser.service.ISysUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;


/**
 * ClassName: SampleRealm 
 * @Description: shiro 认证 + 授权   重写
 * @author JornTang
 * @date 2018年1月28日
 */
public class SimpleRealm extends AuthorizingRealm {
	private static Logger log = LoggerFactory.getLogger(SimpleRealm.class);
	@Autowired
	ISysUserService sysUserService;
	@Autowired
	IPermissionService permissionService;
	@Autowired
	IRoleService roleService;
	
	public SimpleRealm() {
		super();
	}
	/**
	 *  认证信息，主要针对用户登录， 
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(
			AuthenticationToken authcToken) throws AuthenticationException {
		log.info("正在执行用户登录认证......");
		ShiroToken token = (ShiroToken) authcToken;
		SysUser user = sysUserService.login(token.getUsername(),token.getPswd());
		if(null == user){
			throw new AccountException("帐号或密码不正确！");
		/**
		 * 如果用户的status为禁用。那么就抛出<code>DisabledAccountException</code>
		 */
		}else if(SysUser._0.equals(user.getStatus())){
			throw new DisabledAccountException("帐号已经禁止登录！");
		}else{
			//更新用户登录时间 last login time
			user.setLastLoginTime(new Date());
			sysUserService.updateByPrimaryKeySelective(user);
		}
		SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user,user.getPswd(), getName());
		//doGetAuthorizationInfo(SecurityUtils.getSubject().getPrincipals());
		return authenticationInfo;
    }

	/**
	 * 装载用户角色授权信息  此方法为懒加载
	 * 此方法执行三个执行时机: subject.hasRole(“admin”) 
	 * 或 subject.isPermitted(“admin”) 
	 * 或  @RequiresRoles("admin") ：在方法上加注解的时候；
	 */
    @Override  
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {  
    	log.info("正在装载用户权限......");
    	Long userId = TokenManager.getUserId();
		SimpleAuthorizationInfo info =  new SimpleAuthorizationInfo();
		//根据用户ID查询角色（role），放入到Authorization里。
		Set<String> roles = roleService.findRoleByUserId(userId);
		info.setRoles(roles);
		//根据用户ID查询权限（permission），放入到Authorization里。
		Set<String> permissions = permissionService.findPermissionByUserId(userId);
		info.setStringPermissions(permissions);
        return info;  
    }  
    /**
     * 清空当前用户权限信息
     */
    public  void clearCachedAuthorizationInfo() {
		PrincipalCollection principalCollection = SecurityUtils.getSubject().getPrincipals();
		SimplePrincipalCollection principals = new SimplePrincipalCollection(
				principalCollection, getName());
		super.clearCachedAuthorizationInfo(principals);
	}
	/**
	 * 指定principalCollection 清除
	 */
	@Override
	public void clearCachedAuthorizationInfo(PrincipalCollection principalCollection) {
		SimplePrincipalCollection principals = new SimplePrincipalCollection(
				principalCollection, getName());
		super.clearCachedAuthorizationInfo(principals);
	}
}
